package com.shujia.mllib

import org.apache.spark.ml.{feature, linalg}
import org.apache.spark.ml.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import org.apache.spark.mllib.util.MLUtils
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SparkSession}

object Demo01Vector {
  def main(args: Array[String]): Unit = {

    // 什么是向量？ 有方向 有大小
    // 稠密向量
    val denseVec: linalg.Vector = Vectors.dense(Array(1.0, 2.0, 0.0, 0.0, 0.0, 5.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0))

    println(denseVec)

    // 稀疏向量 不会保存值为零的数据 节省空间
    val sparseVec: linalg.Vector = Vectors.sparse(76, Array(0, 1, 5, 6), Array(1.0, 2.0, 5.0, 1.0))
    println(sparseVec)

    // 项目转换
    // 稠密向量 -> 稀疏向量
    println(denseVec.toSparse)
    // 稀疏向量 -> 稠密向量
    println(sparseVec.toDense)

    val spark: SparkSession = SparkSession
      .builder()
      .appName("Demo01Vector")
      .master("local")
      .config("spark.sql.shuffle.partitions", 2)
      .getOrCreate()

    // 文件格式 svm
    // 通过MLUtils读取 可以得到一个RDD
    val dataRDD: RDD[LabeledPoint] = MLUtils.loadLibSVMFile(spark.sparkContext, "Spark/data/mllib/data/人体指标.txt")

    dataRDD.foreach(println)

    val labelPoint: feature.LabeledPoint = org.apache.spark.ml.feature.LabeledPoint(0.0, sparseVec)
    println(labelPoint)

    // 通过Spark SQL读取
    val dataDF: DataFrame = spark
      .read
      .format("libsvm")
      .load("Spark/data/mllib/data/人体指标.txt")
    dataDF.show()

    val imageDF: DataFrame = spark
      .read
      .format("libsvm")
      // 通过稀疏向量 以svm格式保存 数据特征功能处理过后的数据时 会造成特征数量的丢失
      .option("numFeatures", "784")
      .load("Spark/data/mllib/image/libsvm")
    imageDF.show()

  }

}
